/*-------------------<-- Start of Description-->---------------------\ | This macro was written for two purposes: | | 1. Users that have lost the original source code, but still have | | the log, for a program that must be re-run. | | 2. Transfering SAS macro code (with mprint turned on) from the | | log into a runnable program. | |---------------------<-- End of Description-->----------------------| |--------------------------------------------------------------------| |------------<-- Start of Files or Arguments Needed-->---------------| | This is a macro call with the syntax: | | _EXTLOG INFILE='input_log_file' FILE='output_file_name' ; | | | | The program will read the log file, strip all of the line numbers,| | NOTES, WARNINGS, SAS headers, ERROR notices from the file. | | | | There should be no problems extracting most SAS log files, | | espeically if users do not write lines longer than 200 characters.| | | | If the file was generated from a macro the resolved macro code | | will be saved. | | | | Any lines in the log that do not start with a number (or other | | identifier) will not be removed. These lines are usually | | associated with the macro information that has been provided by | | users at the Centre. You will have to search for and delete these| | lines yourself. | |-------------<-- End of Files or Arguments Needed-->----------------| |--------------------------------------------------------------------| |------------------<-- Start of Files Created-->---------------------| | Examples of how to call the macro ; | | _extlog infile='/home/burchil/testing/test.log' | | file='/home/burchil/testing/clean' ; | | _extlog infile='/PHIS/Hospital/testing/test.run.log' | | file='/home/burchil/testing/clean' ; | | _extlog infile='/home/burchil/hosp.service/rates.log' | | file='#junk#'; | | _extlog infile='/home/burchil/testing/test.log' file='#junk#' ; | | Usage: extlog(infile= ,file=,debug=nodebug ); | \-------------------<-- End of Files Created-->---------------------*/ %macro extlog(infile= ,file=,debug=nodebug ) /stmt; %* Test for required file information; %if &infile= %then %goto error; %if &file= %then %goto error; %* Turn on debuging notes if necessary; %if %quote(%upcase(&debug)) = %quote(DEBUG) %then options mprint notes; %else options nomprint nonotes;; %* Create null data set for reading file information, and stripping lines; data _null_; length line $200 macro $20 comment $1; retain cards 'N' err 'N' warn 'N' inval 'N' macro; infile &infile missover delimiter='~'; %* Look for notes and other SAS log lines ; input line & $200. ; if line =:'NOTE' | line=:'real' | line=:'cpu' | line=:'Engine'| line=:'Physical' | line=:'File' | line=:'Owner' | line=:'Access' | line=:'The m' then delete ; %* Test for errors and set warning flag; else if line=:'ERROR' then do; if err = 'N' then err='Y'; delete; end; %* Test for SAS warnings and set flag; else if line=:'WARNING' then do; if warn = 'N' then warn='Y'; delete; end; %* Strip the SAS page title; else if index(line,'The SAS') then delete; %* Stip intro lines from SAS log; else if index(line,'following SAS modules') then delete; else if index(line,'Welcome to the SAS') then delete; else if index(line,'Licensed to') then delete; else if index(line,'BASE GRAPH ETS') then delete; else if index(line,'CALC EIS') then delete; else if index(line,'$Id:') then delete; %* strp various other lines from the file; else if index(line,'compressed would require') then delete; %* strip string conversion notices; else if index(line,'Each place is given by') then do; inval = 'Y'; delete; end; if inval = 'Y' then do; inval = 'N' ; delete; end; %* check if a cards statement was used. The data from card input is usually not printed to the log; if cards='N' & (index(line,'cards') | index(line,'CARDS')) then cards = 'Y'; %* set all flags in macro variables; call symput('cards',cards); call symput('err',err); call symput('warn',warn); %* Define the output file; file &file; %* output SAS code. %* If the code comes from resolved macro code then output the resoved code. If it is the first time the macro is encountered write a note to the code file; if line=:'MPRINT' | line=:'MACROGEN' then do; if macro ^= substr(line,1,indexc(line,':')) then do; macro = substr(line,1,indexc(line,':')); put; put '*** CODE FROM RESOLVED MACRO:' macro ';'; end; line = substr(line,indexc(line,':')+1); end; %* Some times resolved macro code is spread over several lines. The next line catches most (not all) of the multiple line resolved code.; else if ^('1' <= substr(line,1,1) <= '9') then line = line; %* What to do with all the normal SAS code; else line = substr(line,8); %* delete multiple blank lines ; %* Set a lag line variable. This is used to testfor and remvoe blank lines.; lagline = lag(line); if line = '' & lagline = '' then delete; %* put the source code out into the file; put line; run; options nomprint notes;; %if &cards = Y %then %put WARNING: CARDS statement found, data may not be available ; %if &err = Y %then %put WARNING: ERROR notice was found in the log file ; %if &warn = Y %then %put WARNING: WARNING notice was found in the log file ; %put; %put NOTE: Input log file &infile written to output sas file &file; %put; %goto exit; %error: %put WARNING: One of the INFILE, or FILE options was missing; %put . Syntax: _EXTLOG INFILE='log.file' FILE='output.file'; %exit: %mend;